<?php


	// Class :	Template Converter
	// Create:	Admir Serifi (ado@adoweb.ch)
	// Date:	January 2010


	class Template {
	
	    public  $page;
	    public  $url;
	    public $navigations;
	    public  $default;
	    public  $leaf;
	
		
		// Set template Vars
		public function setTemplate($url,$script=null) {
	
			// Parse url
			$this->url = parse_url($url);
			$this->url['url'] = $url;
			$level = 0;
	
			// Set root string
			$countSlash = substr_count($url, '/');
			for ($i = 4; $i <= $countSlash; $i++) {
				$root .= "../";
				$level++;
			}
			
			// Default url values
			$this->url['root'] = $root;
			$this->url['level'] = $level;
			$this->url['framework'] = $this->url['root']."framework/";
			$this->url['template'] = $this->url['framework']."templates/";
			$this->url['config'] = $this->url['framework']."config/";
			$this->url['styles'] = $this->url['framework']."styles/";
			$this->url['lang'] = $this->url['framework']."langs/";
			$this->url['script'] = $this->url['framework']."scripts/";
			
			// Set url folder structure
			$path = explode('/',substr($this->url['path'],1));
			$count = count($path) - 1;
			$this->url['file'] = basename($path[$count]);
			$this->url['filename'] = basename($path[$count],'.php');
			unset($path[$count]);
			
			// Set current url values
			$this->url['category'] = $path[0];
			$this->url['parent'] = ($count > 1) ? $path[$count-2] : "root";
			$this->url['dir'] = ($count == 1) ? $path[0] : $path[$count-1];
	
			// Set default project constants
			$this->default = parse_ini_file($this->url['config'].'config.ini');
			$this->default['root'] = $this->url['root'];
			$this->default['year'] = date('Y');
			$this->default['includScript'] = null;
			$this->default['includStyle'] = null;
			$this->default['framework'] = $this->url['framework'];
			$this->default['styles'] = $this->url['styles'];
			
	
			// Set Navigations array
			$this->navigations = $this->setLang('navigations.ini');
	
		} 
		
		
		// Build html page
		public function constructor($page=null,$extended=null) {
			
			if (is_null($this->page)) {
			
				// If is set constructor selector($page), geti it from ini file
				if (!is_null($page)) {
					$path = $this->url['config']."constructor.ini";
					$file =  parse_ini_file($path, true);
					$constructor = $file[$page];
				}
				// Define new construktor from extended array
				else if (!empty($extended))
					$constructor = $extended;
					
				// if is set constructor selector($page) and extended values
				if (is_array($extended) && !empty($extended)) {
					
					foreach ($extended as $extkey => $extvalue) {
						$constructor[$extkey] = $extvalue;
					}
				}
			
				// Include template file
				include ($this->url['framework']."tmp.php");
	
				$this->page = $tmp['html']."\n";
				
				// Define increment to finde class atributes
				$i = 0; $t = 0;
				
				foreach ($constructor as $block => $tmpArray) {
					
					// Set clearer for template block
					$checkClearer = strpos($block,":");
					
					if ($checkClearer !== false) {
						$var = "";
						$var = explode(":", $block);
						$block = $var[0];
						$clearer[$block][$i] = $var[1];
					}
					
					// Separate all template parts
					$tmpParts = explode(",",$tmpArray);
					
					// Check if template containt one class
					foreach ($tmpParts as $key => $tmpName) {
						$check = strpos($tmpName,":");
						
						if ($check !== false) {
							$var = "";
							$var = explode(":", $tmpName);
							$tmpParts[$key] = $var[0];
							$count = count($var);
							
							if ($count < 3)
								$tmpClass[$var[0]][$i.$t] = $var[1];
							else {
								
								$loopTmp[$var[0]] = "<div id='".$var[0]."'>\n";
								
								for ($n = 1; $n < $count; $n++) {
									
										$loopTmp[$var[0]] .= "<!--".strtoupper($var[$n])."-->\n";
						
										$loopTmp[$var[0]] .= str_replace("{tmpClass}", $var[$n], $tmp[$var[0]])."\n";
						
										$loopTmp[$var[0]] .= "<!--/".strtoupper($var[$n])."-->\n";
								
								}
								
								$loopTmp[$var[0]] .= "</div>\n";
							}
						}
						
						$t++;
					}
					
					// Set value to null
					$tmpName = ""; $t= 0;
					
					// Page bllock
					$this->page .= "<div id='".$block."'>\n";
					
					foreach ($tmpParts as $tmpName) {
						
						// If template containt subtemplates
						if (!is_null($loopTmp[$tmpName])) {
							$setTmp = $loopTmp[$tmpName];
							$blockID = $tmpName;
						}
						// If template containt class
						else if (!is_null($tmpClass[$tmpName][$i.$t])) {
							$setTmp = str_replace("{tmpClass}", $tmpClass[$tmpName][$i.$t], $tmp[$tmpName]);
							$blockID = $tmpClass[$tmpName][$i.$t];
						}
						// For normal template
						else {
							$setTmp = $tmp[$tmpName];
							$blockID = $tmpName;
						}
							
						$this->page .= "<!--".strtoupper($blockID)."-->\n";
						
						$this->page .= $setTmp."\n";
						
						$this->page .= "<!--/".strtoupper($blockID)."-->\n";
						
						$t++; $setTmp = null;
					}
					
					// End page block
					$this->page .= "</div>\n";
					
					// Bllock clearre
					if (!is_null($clearer[$block][$i])) 
							$this->page .= "<div class='".$clearer[$block][$i]."'></div>\n";
					
					$i++; $t=0;
				}
				
				// End of file
				$this->page .= $tmp['/html']."\n";
			}
		}
			
		
		// Page title
		public function pageTitle($title) {
			$this->default['pageTitle'] = $title;
		}
		
		
		// Load language file
		public function setLang($file,$true=true) {
			$path = $this->url['lang']."/".$this->default['lang']."/".$file;
			return parse_ini_file($path, $true);
		}
		
		
		// Load language file
		public function splash($keyword) {
			$path = $this->url['lang']."/".$this->default['lang']."/splash.ini";
			$splash = parse_ini_file($path, $true);
			return $splash['keyword'];
		}
	
	
		// Set page scripts
		public function setStyle($styles,$extended=null) {
			
			if (!empty($styles)) {
				
				foreach ($styles as $foldername => $array) {
					foreach ($array as $filename) {
						
						$return .= "<link rel='stylesheet' type='text/css' href='".$this->url['styles'].$foldername."/".$filename."' />\n";
					}		
				}

				if(!is_null($extended)) {
					$return .= "<style type='text/css'>\n";
					$return .= $extended."\n";
					$return .= "</style>\n";
				}
				
				
				$this->page = str_replace("{includStyle}", $return, $this->page);
			}
			
		}
			
		
		// Set page scripts
		public function setScript($scripts,$extended=null) {
			
			if (!empty($scripts)) {
				
				foreach ($scripts as $foldername => $array) {
					foreach ($array as $filename) {
						
						$return .= "<script type='text/javascript' src='".$this->url['script'].$foldername."/".$filename."'></script>\n";
					}		
				}

				if(!is_null($extended)) {
					$return .= "<script type='text/javascript'>\n";
					$return .= $extended."\n";
					$return .= "</script>\n";
				}
				
				$this->page = str_replace("{includScript}", $return, $this->page);
			}
			
		}
		
		
		// Load file from framework
		public function loadFile($path) {
			
			$file = $this->url['framework'].$path;
			
			if (file_exists($file)) {
				$fp = fopen($file, "r");
				$content = fread($fp, filesize($file));
				fclose($fp);
			}
			
			return $content;
		}
		
		
		// Set render method
		public function render($param1,$param2=null) {

			// 2D-Array converting (key => value)
			if (is_array($param1))
				$this->setVars($param1);
			// Destroy template part
			elseif(!is_array($param1) && $param2 == null)
				$this->destroyBlock($param1);
			// 3D-Array converting (key => array(key => value))
			else
				$this->setLoop($param1, $param2);
		}
	
	
		// Search match i template
		private function setMatch($content,$delimiter) {

			// Return array
			$return = array();

			// Search pattern
			$pattern = array("labels" => "#\|(.*?)\|#",
							 "vars" => "#\{\(.*?)\}#",
							 "errors" => "#\?\(.*?)\?#",
							 "options" => "#\%(.*?)\%#" );

			preg_match_all($pattern[$delimiter], $content, $match);

			// Remove first key from array,
			unset($match[0]);

			foreach ($match as $key => $array) {

				// Drop double values
				$array = array_unique($array);

				foreach ($array as $subkey => $section) {
					$return[] = $section;
				}
			}

			return $return;
		}
	
	
		// Navigation
		public function category() {
			
			$categorys = $this->navigations['category'];
	
			foreach($categorys as $key => $value) {
				
				if ($key == "index") {
					$key = "index.php";
					if ($this->url['level']  == 0) $class = "current";
				} 
				else 
					$class = ($this->url['category'] == $key) ? "current" : null;
				
				$return[] = array("link" => $this->url['root'].$key,"class" => $class,"menu" => $value);
			}
	
			return $return;
		}
	
	
		// Sections
		public function sections($sid) {
	
			$sql = mysql_query("SELECT section_id, section_name FROM section WHERE section_access != '0'");
	
			while ($row = mysql_fetch_assoc($sql)) {
				
				$check = mysql_query("SELECT book_section_id FROM book WHERE book_section_id = '".$row['section_id']."'");
				
				if (mysql_num_rows($check) > 0) {
	
					$menu['class'] = ($sid == $row['section_id']) ? "current" : null;
					$menu['link'] = "sections.php?sid=".$row['section_id'];
					$menu['menu'] = $row['section_name'];
					$return[] = $menu;
				}
			}
	
			return $return;
		}
	
	
		// Navigation
		public function navigation($name,$getLevel=0) {
			
			if (!is_null($name)) {
				
				// Forward first get var
				if (!is_null($this->url['query']) && !is_null($getLevel)) {
					
					$urlQuery = explode("&", $this->url['query']);
					$get = "?";
					
					for ($i = 0; $i <= $getLevel; $i++) {
						$get .= $urlQuery[$i];
						if ($i < $getLevel) $get .= "&";
					}
					
				}
	
				$navigations = $this->navigations[$name];
		
				foreach($navigations as $key => $value) {
		
					$class = ($this->url['filename'] == $key) ? "current" : null;
					$return[] = array("link" => $key.".php".$get,"class" => $class,"menu" => $value);
				}
			}
		
			return $return;
		}
		
		
		// Set labels
		public function show() {
	
			// Set Labels Array
			$labels = $this->setLang("labels.ini");
			$labels['copyright'] = "2002 - ".date('Y');
			$labelMatch = $this->setMatch($this->page,"labels");
	
			foreach ($labelMatch as $key) {
	
				$search[] = '|'.$key.'|';
				$replace[] = $labels[$key];
			}

			$this->page = str_replace($search,$replace,$this->page);
			
			$replace['pageTitle'] = $this->default['name'];

			$this->render($this->default);
			
			echo $this->page;
		}
	
	
		// Set options
		public function setOptions($extOptions=NULL) {

			$options = $this->setLang("options.ini");

			// Merge all options arrays
			if (is_array($extOptions))
				$options = array_merge($options,$extOptions);

			$matchs = $this->setMatch($this->page,"options");

			// Find all options match in tampleta
			foreach ($matchs as $keyword) {
				if (!empty($options[$keyword])) {
					foreach ($options[$keyword] as $key => $value) {
						$selected = (!empty($_POST[$keyword]) && $_POST[$keyword] == $key) ? "selected" : "";
						$return[$keyword] .= "<option value='$key' $selected>$value</option>";
					}
				}
			}

			foreach ($return as $searchKey => $replaceValue) {

				$search[] = '%'.$searchKey.'%';
				$replace[] = $replaceValue;
			}

			$this->page = str_replace($search, $replace, $this->page);
		}
		
		
		// Page details
		public function leaf($page,$sql) {
	
			$this->leaf['current'] = ($page != NULL) ? $page : 1;
			$this->leaf['offset'] = ($this->leaf['current'] - 1) * $this->default['rowsPerPage'];
			$this->leaf['rows'] = mysql_num_rows(mysql_query($sql));
			$this->leaf['maxrows'] = ceil($this->leaf['rows'] / $this->default['rowsPerPage']);
			$this->leaf['left'] = "|totalrows|: ".$this->leaf['rows']." |books|";
	
			if ($this->leaf['maxrows'] > 1) {
	
				for ($i = 1; $i <= $this->leaf['maxrows']; $i++) {
					$currClass = ($this->leaf['current'] == $i) ? "class='current'" : "";
					$right .= "<a href='".$this->url['file']."?sid=".$this->url['sid']."&page=".$i."' $currClass>$i</a>";
				}
			}
			
			$this->leaf['right'] = $right;
	
		}
	
	
		// Process FORM variables ($_POST and $ERRORS)
		public function setForm($errors=null) {
	
			// Values
			$varmatchs= $this->setMatch($this->page,"vars");
	
			foreach ($varmatchs as $key) {
	
				$values[$key] = $postValues[$key];
			}
	
			$this->render("FORM",$values);
	
			// Errors
			$errors= setLang("errors.ini");
	
			// Matchs
			$errmatchs = $this->setMatch($this->page,"errors");
	
			foreach ($errmatchs as $key) {
	
				$search[] = "?".$key."?";
				$replace[] = (empty($postErrors[$key])) ? null : "<span class='error'>".$errors[$postErrors[$key]]."</span>";
			}
	
			$this->page = str_replace($search, $replace, $this->page);
		}

	
		// Vars converter
		private function setVars($array) {

			if (!empty($array)) {
				foreach ($array as $key => $value) {
					$search[] = '{'.$key.'}';
					$replace[] = $value;
				}

				$this->page = str_replace($search, $replace, $this->page);
			}
		}
		
		
		// Bllock destroy
		private function destroyBlock($section) {

			// Convert end of part
			$convert = str_replace("<!--/".$section."-->", "<!--".$section."-->", $this->page);

			// Split the part of Template dependet from section
			$tmpParts = explode("<!--".$section."-->", $convert);
			unset($tmpParts[1]);

			$this->page = implode($tmpParts);
		}
		
		
		// Loop converter
		private function loopVars($array,$loopPart) {

			if (!empty($array)) {
				foreach ($array as $key => $value) {
					$search[] = '{'.$key.'}';
					$replace[] = $value;
				}

				return str_replace($search, $replace, $loopPart);
			}
		}
	
	
		// Looping
		private function setLoop($section, $array) {
			
			// Convert end of part
			$convert = str_replace("<!--/".$section."-->", "<!--".$section."-->", $this->page);

			// Split the part of Template dependet from section
			$tmpParts = explode("<!--".$section."-->", $convert);

			// Loop render
			if(strpos($tmpParts[1], "<!--loop-->") != NULL) {

				// Split looping part
				$loopParts = explode("<!--loop-->", str_replace("<!--/loop-->","<!--loop-->", $tmpParts[1]));

				// For every part, convert array variabels
				foreach ($array as $subarray) {
					$Part .= $this->loopVars($subarray, $loopParts[1]);
				}
			}
			// No-Loop render
			else
				$Part .= $this->loopVars($array, $tmpParts[1]);

			// Merge first and last part of Loop sections
			$return = $loopParts[0].$Part.$loopParts[2];

			$this->page = $tmpParts[0].$return.$tmpParts[2];
		}
	}
?>